package Thread.mq;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicInteger;

import static Thread.mq.Common.*;

/**
 * Created by sunyuming on 18/10/23.
 */
public class MyBlockingQueue {

    private static BlockingQueue<MyInteger> arrayBlockingQueue = new LinkedBlockingDeque<MyInteger>(LEN);

    public static void main(String[] args) {

        CountDownLatch start = new CountDownLatch(1);
        CountDownLatch end = new CountDownLatch(1);

        Runnable producer = new Producer(start);
        Runnable customer = new Customer(end);
        for(int i=0; i<threadCount; ++i) {
            new Thread(producer).start();
            new Thread(customer).start();
        }

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        start.countDown();
        try {
            end.await();
            System.out.println("耗时" + String.valueOf(ed-st));

        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }

    private static class Producer implements Runnable {

        private AtomicInteger atomicInteger = new AtomicInteger(0);

        private CountDownLatch countDownLatch;
        public Producer(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            try {
                countDownLatch.await();
                st = System.currentTimeMillis();

                for(int i=0; i<LEN; ++i) {
                    arrayBlockingQueue.put(new MyInteger(atomicInteger.incrementAndGet()));
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static class Customer implements Runnable {

        private CountDownLatch countDownLatch;
        public Customer(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            try {
                for(int i=0; ; ++i) {
                    MyInteger myInteger = arrayBlockingQueue.take();
                    if(myInteger.last()) {
                        ed = System.currentTimeMillis();
                        countDownLatch.countDown();
                        System.out.println(myInteger.mem);
                    }
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

}
